import React, { useState, useEffect } from 'react';
import { Link } from 'react-router';
import styles from '../../Common/Layout/LeftSubSidebar/LeftSubSidebar.scss';
import {
  getFunctionModifyRoute,
  getTableBrowseRoute,
} from '../../Common/utils/routesUtils';
import GqlCompatibilityWarning from '../../Common/GqlCompatibilityWarning/GqlCompatibilityWarning';

type SourceItemsTypes =
  | 'database'
  | 'schema'
  | 'view'
  | 'enum'
  | 'function'
  | 'table';

type SourceItem = {
  name: string;
  type: SourceItemsTypes;
  children?: SourceItem[];
};

const activeStyle = {
  color: '#fd9540',
};

type LeafItemsViewProps = {
  item: SourceItem;
  currentSource: string;
  currentSchema: string;
  pathname: string;
};
const LeafItemsView: React.FC<LeafItemsViewProps> = ({
  item,
  currentSource,
  currentSchema,
  pathname,
}) => {
  const [isOpen, setIsOpen] = useState(false);
  const regex = new RegExp(
    `\\/data\\/${currentSource}\\/schema\\/${currentSchema}\\/(tables|functions|views)\\/${item.name}\\/`
  );
  const isActive = regex.test(pathname);

  const isView = item.type === 'view';

  const iconStyle = {
    marginRight: '5px',
    fontSize: '12px',
    width: '12px',
  };

  const activeIcon =
    '';
  const nonActiveIcon =
    '';

  return (
    <>
      <div
        className={styles.sidebarTablePadding}
        onClick={() => {
          setIsOpen(prev => !prev);
        }}
        onKeyDown={() => {
          setIsOpen(prev => !prev);
        }}
        role="button"
      >
        <span
          className={
            item.children &&
            `${styles.title} ${isOpen ? '' : styles.titleClosed}`
          }
        >
          {item.type === 'function' ? (
            <Link
              to={getFunctionModifyRoute(
                currentSchema,
                currentSource,
                item.name
              )}
              data-test={item.name}
              style={isActive ? activeStyle : {}}
            >
              <img
                style={iconStyle}
                src={isActive ? activeIcon : nonActiveIcon}
                alt="function icon"
              />
              {item.name}
            </Link>
          ) : (
            <>
              <Link
                to={getTableBrowseRoute(
                  currentSchema,
                  currentSource,
                  item.name,
                  !isView
                )}
                data-test={item.name}
                style={isActive ? activeStyle : {}}
              >
                {item.type === 'enum' ? (
                  <i className="fa fa-list-ul" />
                ) : (
                  <i className="fa fa-table" />
                )}
                {item.type === 'view' ? <i>{item.name}</i> : item.name}
              </Link>
              <GqlCompatibilityWarning
                identifier={item.name}
                className={styles.add_mar_left_mid}
                ifWarningCanBeFixed
              />
            </>
          )}
        </span>
      </div>
    </>
  );
};

type SchemaItemsViewProps = {
  item: SourceItem;
  currentSource: string;
  isActive: boolean;
  setActiveSchema: (value: string) => void;
  pathname: string;
  databaseLoading: boolean;
};
const SchemaItemsView: React.FC<SchemaItemsViewProps> = ({
  item,
  currentSource,
  isActive,
  setActiveSchema,
  pathname,
  databaseLoading,
}) => {
  const [isOpen, setIsOpen] = useState(false);
  const showActiveStyle =
    pathname === `/data/${currentSource}/schema/${item.name}`;
  useEffect(() => {
    setIsOpen(isActive);
  }, [isActive]);

  return (
    <>
      <div
        onClick={() => {
          setActiveSchema(encodeURIComponent(item.name));
        }}
        onKeyDown={() => {
          setActiveSchema(encodeURIComponent(item.name));
        }}
        role="button"
        className={styles.padd_bottom_small}
        style={showActiveStyle ? activeStyle : {}}
      >
        <span
          className={
            item.children &&
            `${styles.title} ${isOpen ? '' : styles.titleClosed}`
          }
        >
          <i className={`${isOpen ? 'fa fa-folder-open' : 'fa fa-folder'}`} />{' '}
          {item.name}
        </span>
      </div>
      <ul className={styles.reducedChildPadding}>
        {isOpen && item.children ? (
          !databaseLoading ? (
            item.children.map((child, key) => (
              <li key={key}>
                <LeafItemsView
                  item={child}
                  currentSource={currentSource}
                  currentSchema={item.name}
                  key={key}
                  pathname={pathname}
                />
              </li>
            ))
          ) : (
            <li>
              <span
                className={`${styles.sidebarTablePadding} ${styles.padd_bottom_small}`}
              >
                <i className="fa fa-table" />
                <span className={styles.loaderBar} />
              </span>
            </li>
          )
        ) : null}
      </ul>
    </>
  );
};

type DatabaseItemsViewProps = {
  item: SourceItem;
  isActive: boolean;
  setActiveDataSource: (activeSource: string) => void;
  onSchemaChange: (value: string) => void;
  currentSchema: string;
  pathname: string;
  databaseLoading: boolean;
};
const DatabaseItemsView: React.FC<DatabaseItemsViewProps> = ({
  item,
  isActive,
  setActiveDataSource,
  onSchemaChange,
  currentSchema,
  pathname,
  databaseLoading,
}) => {
  const [isOpen, setIsOpen] = useState(false);
  const showActiveStyle = [
    `/data/${item.name}/`,
    `/data/${item.name}`,
    `/data/${item.name}/display`,
    `/data/${item.name}/gallery`,
  ].includes(pathname);

  useEffect(() => {
    setIsOpen(isActive);
  }, [isActive]);
  const handleSelectSchema = (value: string) => {
    onSchemaChange(value);
  };

  return (
    <div className={styles.padd_bottom_small}>
      <div
        onClick={() => {
          setActiveDataSource(item.name);
        }}
        onKeyDown={() => {
          setActiveDataSource(item.name);
        }}
        role="button"
        className={styles.padd_bottom_small}
      >
        <span
          className={
            item.children &&
            `${styles.title} ${isOpen ? '' : styles.titleClosed}`
          }
          style={showActiveStyle ? activeStyle : {}}
        >
          <i className={`fa fa-${item.type}`} /> {item.name}
        </span>
      </div>
      {isOpen && item.children
        ? item.children.map((child, key) => (
            <li key={key}>
              <SchemaItemsView
                item={child}
                currentSource={item.name}
                isActive={child.name === currentSchema}
                setActiveSchema={handleSelectSchema}
                key={key}
                pathname={pathname}
                databaseLoading={databaseLoading}
              />
            </li>
          ))
        : null}
      {databaseLoading && isActive ? (
        <li>
          <span
            className={`${styles.title} ${styles.titleClosed} ${styles.padd_bottom_small}`}
          >
            <i className="fa fa-folder" />
            <span className={styles.loaderBar} />
          </span>
        </li>
      ) : null}
    </div>
  );
};

type TreeViewProps = {
  items: SourceItem[];
  onDatabaseChange: (value: string) => void;
  onSchemaChange: (value: string) => void;
  currentDataSource: string;
  currentSchema: string;
  pathname: string;
  databaseLoading: boolean;
  preLoadState: boolean;
};
const TreeView: React.FC<TreeViewProps> = ({
  items,
  onDatabaseChange,
  currentDataSource,
  onSchemaChange,
  currentSchema,
  pathname,
  databaseLoading,
  preLoadState,
}) => {
  const handleSelectDataSource = (dataSource: string) => {
    onDatabaseChange(dataSource);
  };

  if (items.length === 0) {
    return preLoadState ? (
      <div className={styles.treeNav}>
        <span className={`${styles.title} ${styles.padd_bottom_small}`}>
          <i className="fa fa-database" />
        </span>
        <span className={styles.loaderBar} />
        <li>
          <span className={`${styles.title} ${styles.padd_bottom_small}`}>
            <i className="fa fa-folder" />
            <span className={styles.loaderBar} />
            <ul className={styles.reducedChildPadding}>
              <li
                className={`${styles.sidebarTablePadding} ${styles.add_mar_left_mid}`}
              >
                <i className="fa fa-table" />
                <span className={styles.loaderBar} />
              </li>
            </ul>
          </span>
        </li>
      </div>
    ) : (
      <li className={styles.noChildren} data-test="sidebar-no-services">
        <i>No data available</i>
      </li>
    );
  }

  return (
    <div className={styles.treeNav}>
      {items.map((item, key) => (
        <DatabaseItemsView
          item={item}
          onSchemaChange={onSchemaChange}
          key={key}
          isActive={currentDataSource === item.name}
          setActiveDataSource={handleSelectDataSource}
          currentSchema={currentSchema}
          pathname={pathname}
          databaseLoading={databaseLoading}
        />
      ))}
    </div>
  );
};

export default TreeView;
